#include "BlockQueue.hpp"
#include <ctime>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>


template<class T,class S>
class BlockQueues{
public:
    blockqueue<T>* _task;
    blockqueue<S>* _save;
};

//生产者
void *production(void *args)
{
    //blockqueue<CalTask> *bp = static_cast<blockqueue<CalTask> *>(args);
    blockqueue<CalTask> *bp = (static_cast<BlockQueues<CalTask,SaveTask> *>(args))->_task;
    while (true)
    {
        char op = _opes[rand() % 5];
        int x = rand() % 10;
        int y = rand() % 5;
        CalTask t(x, y,op, myMath);
        bp->_push(t);
        cout << "productor thread, 生产计算任务  :" << t.Tostring() << endl;
    }
    return nullptr;
}

//消费者
void *comsume(void *args)
{
    // blockqueue<CalTask> *bp = static_cast<blockqueue<CalTask> *>(args);
    blockqueue<CalTask> *bp = (static_cast<BlockQueues<CalTask,SaveTask> *>(args))->_task;
    blockqueue<SaveTask> *bp_save = (static_cast<BlockQueues<CalTask,SaveTask> *>(args))->_save;


    while (true)
    {
        CalTask t;
        bp->_pop(&t);
        std::string result = t(); //任务非常耗时！！！

        cout << "cal thread ,完成计算任务 " <<result <<"....done"<< endl;


        //Save的命令
        SaveTask save(result,Save);
        bp_save->_push(save);
        std::cout<<"cal thread ,推送存储任务完成...."<<endl;
        sleep(2);
    }
    return nullptr;
}

void* saver(void* args)
{
    blockqueue<SaveTask>* save_bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->_save;

    while(true)
    {
        SaveTask t;
        save_bq->_pop(&t);
        t();
        std::cout<<"save thread,保存任务完成..."<<std::endl;
    }
    return nullptr;
}

int main()
{

    pthread_t c, p,s;
    srand((unsigned int)time(nullptr) ^ getpid());
    //blockqueue<Task> *_bp = new blockqueue<Task>(); // 创建一个bp的对象
    BlockQueues<CalTask,SaveTask> _bp;
    _bp._task = new blockqueue<CalTask>();
    _bp._save = new blockqueue<SaveTask>();
    // 创建三个线程
    pthread_create(&c, nullptr, comsume, &_bp);
    pthread_create(&p, nullptr, production, &_bp);
    pthread_create(&s, nullptr, saver, &_bp);

    

    // 等待三个线程
    pthread_join(c, nullptr);
    pthread_join(p, nullptr);
    pthread_join(s, nullptr);

    delete _bp._task;
    delete _bp._save;

    return 0;
}